package com.wiscamp.ninechapters.problems.application.services;

import com.wiscamp.ninechapters.common.core.CollectionHelper;
import com.wiscamp.ninechapters.common.core.RandomHelper;
import com.wiscamp.ninechapters.problems.application.assemblers.ProblemAssembler;
import com.wiscamp.ninechapters.problems.application.assemblers.TaskReportAssembler;
import com.wiscamp.ninechapters.problems.application.dto.commands.reports.CreateTaskByReportCommand;
import com.wiscamp.ninechapters.problems.application.dto.vo.problems.ProblemKnowledgePointVO;
import com.wiscamp.ninechapters.problems.application.dto.vo.reports.TaskReportVO;
import com.wiscamp.ninechapters.problems.domain.gateway.TagGateway;
import com.wiscamp.ninechapters.problems.domain.models.challenges.AmcSummaryReport;
import com.wiscamp.ninechapters.problems.domain.models.problems.problems.ProblemKnowledgePoint;
import com.wiscamp.ninechapters.problems.domain.services.ProblemSetService;
import com.wiscamp.ninechapters.problems.domain.services.TaskReportService;
import com.wiscamp.ninechapters.problems.domain.services.TaskService;
import cube.ddd.application.BaseAppService;
import cube.ddd.aspect.HandleServiceException;
import cube.ddd.aspect.HandleServiceException;
import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.stream.Collectors;

@Service
public class TaskReportAppService extends BaseAppService {

    private final TaskReportService taskReportService;

    private final ProblemSetService problemSetService;

    private final TaskService taskService;

    private final TagGateway tagGateway;

    public TaskReportAppService(TaskReportService taskReportService, ProblemSetService problemSetService, TaskService taskService, TagGateway tagGateway) {
        this.taskReportService = taskReportService;
        this.problemSetService = problemSetService;
        this.taskService = taskService;
        this.tagGateway = tagGateway;
    }

    /**
     * Creates a new practice task by incorrect items of a report
     * 通过练习报告中的错题组成新的练习任务
     *
     * @param taskId
     * @param quantity
     * @return
     */
    @HandleServiceException
    public boolean createTaskByReport(@NotNull CreateTaskByReportCommand command) {
        command.setOperatorId(getCurrentUserId());
        var taskId = command.getTaskId();
        var quantity = command.getProblemQuantity();
        var report = taskReportService.getReportByTask(taskId);
        if (report == null) return false;
        var points = taskReportService.getPointsByIncorrectProblemsInReport(taskId);
        if (points.size() <= 0) return false;
        var pointIds = points.stream().map(ProblemKnowledgePoint::getPointId).distinct().collect(Collectors.toList());

        Collection<Long> problemIds = tagGateway.getProblemIdsByKnowledgePoints(pointIds);
        problemIds = RandomHelper.getRandomCollection(problemIds, quantity);
        if (problemIds.size() <= 0) return false;
        var set = problemSetService.createProblemSetByProblems(problemIds, report.getUserId(), "", "", 0, 0);
        if (set == null) return false;
        var userIds = new ArrayList<Long>();
        userIds.add(report.getUserId());
        taskService.createTasksBySet(set.getSetId(), userIds, 0);
        return true;
    }

    public AmcSummaryReport analyseAmcScore(long taskId) {
        /*TaskReport report = taskReportService.getReportByTask(taskId);
        Collection<ReportQuestion> reportItems = report.getReportItems();

        double totalScore = report.getTotalGainScore();

        AmcSummaryReport summaryReport = new AmcSummaryReport();
        summaryReport.setReportType("AMC");
        summaryReport.setTotalScore(report.getTotalGainScore());
        summaryReport.setCorrectQuestionQty(report.getCorrectProblemQuantity());
        summaryReport.setQuestionQty(reportItems.size());
        summaryReport.setTaskId(taskId);
        summaryReport.setUsedSeconds(report.getTotalSpendSeconds());
        summaryReport.setUserId(report.getUserId());

        var task = taskRepository.getTask(taskId);
        long setId = task.getSetId();
        var set = problemSetService.getProblemSet(setId);
        String setName = set.getSetName();
        long examId = 0;
        if (setName.contains("AMC8")) {
            examId = 510;
            summaryReport.setReportType("AMC8");
        }
        if (setName.contains("AMC10A") || setName.contains("AMC10B")) {
            examId = 520;
            summaryReport.setReportType("AMC10");
        }
        if (setName.contains("AMC12A") || setName.contains("AMC12B")) {
            examId = 530;
            summaryReport.setReportType("AMC12");
        }
        String abPaper = "";
        if (setName.contains("10A") || setName.contains("12A"))
            abPaper = "A";
        if (setName.contains("10B") || setName.contains("12B"))
            abPaper = "B";

        var statistic = taskReportRepository.getAmcStatistic(examId, set.parseSetYear(), abPaper);
        if (statistic == null)
            statistic = taskReportRepository.getAmcStatistic(examId, 9999, abPaper);
        summaryReport.setAmcStatistic(statistic);
        return summaryReport;*/
        return null;
    }

    @HandleServiceException
    public Collection<ProblemKnowledgePointVO> getPointsByIncorrectProblemsInReport(@Min(0) long taskId) {
        var points = taskReportService.getPointsByIncorrectProblemsInReport(taskId);
        return CollectionHelper.convertToArrayList(points, ProblemAssembler.Instance::toProblemKnowledgePointVO);
    }

    @HandleServiceException
    public int getIncorrectProblemQuantity(@Min(0) long taskId) {
        return taskReportService.getIncorrectProblemQuantity(taskId);
    }

    @HandleServiceException
    public TaskReportVO getReportByTask(@Min(0) long taskId) {
        var report = taskReportService.getReportByTask(taskId);
        return TaskReportAssembler.Instance.toTaskReportVO(report);
    }
}
